﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Infrastructure.Dao;
using WsdShop.IService;
using WsdShop.Model.SearchModels;
using WsdShop.Model.ViewModels;
using SqlSugar;
using WsdShop.Model;
using Infrastructure;
using ServiceStack;

namespace WsdShop.Service
{
    public class SpikeService : ISpikeService
    {

        public List<SpikeResponse> SpikeManage(SpikeManageSearchModel search, out int total)
        {
            using (var Db = DbConfig.GetInstance())
            {
                var response = new List<SpikeResponse>();
                Db.CurrentFilterKey = "";
                Sqlable sable = Db.Sqlable().From<Activity_Spike>("P");
                sable.Join<Activity_SpikeSpec>("PS", "PS.SpikeId", "P.Id", JoinType.Left);
                sable.Where(" P.IsDeleted=0 AND PS.IsDeleted=0 ");
                if (!search.Keywords.IsNullOrEmpty())
                {
                    sable.Where(" (P.Name like @Name or P.SubTitle like @SubTitle) ");
                }

                if (search.StartTimeParm != null)
                {
                    sable.Where(" P.BeginTime >=@StartTimeParm ");
                }

                if (search.EndTimeParm != null)
                {
                    sable.Where(" P.BeginTime <=@EndTimeParm ");
                }

                var pars = new { Name = "%" + search.Keywords + "%", SubTitle = "%" + search.Keywords + "%", StartTimeParm = search.StartTimeParm, EndTimeParm = search.EndTimeParm };
                sable.GroupBy = "GROUP BY P.Id,P.Name,P.BeginTime,P.EndTime,P.SubTitle,P.HeadPicUrl,P.AddTime";
                total = sable.SelectToList<Activity_Spike>("P.Id", pars).Count;
                response = sable.SelectToPageList<SpikeResponse>("P.Id,P.Name,P.BeginTime,P.EndTime,P.SubTitle,P.HeadPicUrl,P.AddTime,SUM(PS.Stock) AS TotalStock,SUM(PS.SpikeStock) AS TotalSpikeStock", "P." + search.OrderByFields, search.Skip / search.Take + 1, search.Take, pars);

                return response;
            }
        }


        public Result DelSpike(int Id, int currentUserId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                var spike = Db.Queryable<Activity_Spike>().SingleOrDefault(m => m.Id == Id);
                if (spike == null || spike.Id == 0)
                {
                    return Result.Failure("该活动不存在或已删除");
                }
                if (spike.BeginTime <= DateTime.Now && spike.EndTime >= DateTime.Now)
                {
                    return Result.Failure("活动正在进行，无法删除，您可以提前关闭并结束该活动");
                }

                spike.IsDeleted = true;
                spike.EditTime = DateTime.Now;
                spike.EditUserId = currentUserId;
                Db.Update(spike);
                return Result.Success();
            }
        }


        public Result ChangeSpikeState(int Id, int currentUserId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                var spike = Db.Queryable<Activity_Spike>().SingleOrDefault(m => m.Id == Id);
                if (spike == null || spike.Id == 0)
                {
                    return Result.Failure("该活动不存在或已删除");
                }
                if (spike.BeginTime > DateTime.Now)
                {
                    spike.BeginTime = DateTime.Now;
                }
                else if (spike.EndTime > DateTime.Now)
                {
                    spike.EndTime = DateTime.Now;
                }
                else
                {
                    return Result.Failure("已结束活动不可改变活动状态");
                }

                spike.EditTime = DateTime.Now;
                spike.EditUserId = currentUserId;
                Db.Update(spike);
                return Result.Success(spike.ConvertTo<SpikeResponse>().ToJson());
            }
        }


        public Result ChangeSpikeEndTime(int Id, DateTime EndTime, int currentUserId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                var spike = Db.Queryable<Activity_Spike>().SingleOrDefault(m => m.Id == Id);
                if (spike == null || spike.Id == 0)
                {
                    return Result.Failure("该活动不存在或已删除");
                }
                if (EndTime < spike.EndTime)
                {
                    return Result.Failure("延长后时间不能小于原来的结束时间！");
                }

                spike.EndTime = EndTime;
                spike.EditTime = DateTime.Now;
                spike.EditUserId = currentUserId;
                Db.Update(spike);
                return Result.Success();
            }
        }


        public SpikeEditResponse SpikeEdit(int Id)
        {
            using (var Db = DbConfig.GetInstance())
            {
                var response = new SpikeEditResponse { Activity = new SpikeResponse(), SpikeActivityInfoList = new List<SpikeSpecResponse>() };

                if (Id > 0)
                {
                    response.Activity = Db.Queryable<Activity_Spike>().SingleOrDefault(m => m.Id == Id).ConvertTo<SpikeResponse>();
                    Db.CurrentFilterKey = "";
                    Sqlable sable = Db.Sqlable().From<Activity_SpikeSpec>("ASP");
                    sable.Join<Product>("P", "P.Sku", "ASP.ProductSku", JoinType.Left);
                    sable.Join<Product_Spec>("PS", "PS.ProductSku", "ASP.ProductSku", JoinType.Left);
                    sable.Where(string.Format(" P.IsDeleted=0 AND PS.IsDeleted=0 AND ASP.IsDeleted=0 AND ASP.SpikeId={0} ", Id));

                    sable.GroupBy = "GROUP BY ASP.Id,ASP.AddUserId,ASP.AddTime,ASP.EditUserId,ASP.EditTime,ASP.IsDeleted,ASP.SpikeId,ASP.ProductSku,ASP.Price,ASP.SpikeStock,ASP.Limit,ASP.Stock,P.ImgUrl,P.Name";
                    response.SpikeActivityInfoList = sable.SelectToList<SpikeSpecResponse>("ASP.Id,ASP.AddUserId,ASP.AddTime,ASP.EditUserId,ASP.EditTime,ASP.IsDeleted,ASP.SpikeId,ASP.ProductSku,ASP.Price,ASP.SpikeStock,ASP.Limit,ASP.Stock,P.Name,P.ImgUrl,MAX(PS.MarketPrice) AS 'MarketPrice',MIN(PS.Price) AS 'SalePrice',SUM(PS.Stock-PS.WaitSendStock) AS 'CanSaleStock'");

                }
                return response;
            }
        }


        public Result SpikeEditSubmit(Activity_Spike Activity, List<Activity_SpikeSpec> SpikeActivityProductSelectedList, int currentUserId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                if (Activity == null || SpikeActivityProductSelectedList == null ||
                SpikeActivityProductSelectedList.Count == 0)
                {
                    return Result.Failure("传入参数有误，活动及关联产品不可为空");
                }
                if (Activity.BeginTime > Activity.EndTime)
                {
                    return Result.Failure("活动开始时间不可大于结束时间");
                }

                int activityId = Activity.Id;
                Activity.ShareTitle = Activity.ShareTitle ?? Activity.Name;
                Activity.ShareContent = Activity.ShareContent ?? Activity.SubTitle;
                if (Activity.Id == 0)
                {
                    Activity.AddUserId = currentUserId;
                    activityId = Db.Insert(Activity, true).ObjToInt();
                }
                else
                {
                    Activity.EditTime = DateTime.Now;
                    Activity.EditUserId = currentUserId;
                    Db.Update(Activity);
                }

                var spikespeclist = Db.Queryable<Activity_SpikeSpec>().Where(m => m.SpikeId == activityId).ToList() ?? new List<Activity_SpikeSpec>();

                //删除
                var needDeleteList = spikespeclist.Where(m => SpikeActivityProductSelectedList.All(n => n.Id != m.Id)).ToList();
                foreach (var item in needDeleteList)
                {
                    item.IsDeleted = true;
                    item.EditTime = DateTime.Now;
                    item.EditUserId = currentUserId;
                    Db.Update(item);
                }

                //更新及添加
                foreach (var item in SpikeActivityProductSelectedList)
                {
                    item.SpikeId = activityId;
                    item.AddUserId = (item.Id == 0 ? currentUserId : item.AddUserId);
                    item.EditUserId = (item.Id == 0 ? item.EditUserId : currentUserId);
                    item.EditTime = (item.Id == 0 ? item.EditTime : DateTime.Now);
                    Db.InsertOrUpdate(item);
                }
                return Result.Success();
            }
        }


        #region WAP




        public List<SpikeListResponse> GetSpikeList()
        {
            using (var Db = DbConfig.GetInstance())
            {
                var response = new List<SpikeListResponse>();
                var begintime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd 00:00:00"));
                var endtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd 23:59:59"));
                var spikelist = Db.Queryable<Activity_Spike>().Where(m => m.BeginTime >= begintime && m.BeginTime <= endtime).OrderBy(o => o.BeginTime).ToList() ?? new List<Activity_Spike>();
                spikelist.ForEach(m =>
                {
                    var spike = m.ConvertTo<SpikeListResponse>();
                    Db.CurrentFilterKey = "";
                    Sqlable sqlable = Db.Sqlable().From<Activity_SpikeSpec>("ASS");
                    sqlable.Join<Product>("P", "P.Sku", "ASS.ProductSku", JoinType.Left);
                    sqlable.Join<Product_Spec>("PS", "PS.ProductSku", "ASS.ProductSku", JoinType.Left);

                    sqlable.Where(string.Format(" P.IsDeleted=0 AND PS.IsDeleted=0 AND ASS.IsDeleted=0 AND ASS.SpikeId={0} ", m.Id));

                    sqlable.GroupBy = @"GROUP BY ASS.Id ,
                                                                        ASS.AddUserId ,
                                                                        ASS.AddTime ,
                                                                        ASS.EditUserId ,
                                                                        ASS.EditTime ,
                                                                        ASS.IsDeleted ,
                                                                        ASS.SpikeId ,
                                                                        ASS.ProductSku ,
                                                                        ASS.Price ,
                                                                        ASS.SpikeStock ,
                                                                        ASS.Limit ,
                                                                        ASS.Stock,
                                                                        P.Name,
                                                                        P.ImgUrl,
                                                                        P.Sort 
                                                                        Order by P.Sort Desc ";
                    //sqlable.OrderBy(" Order by P.Sort Desc ";
                    spike.SpikeProductList = sqlable.SelectToList<SpikeProductResponse>(@"ASS.Id ,
                                                                                                                                      ASS.AddUserId ,
                                                                                                                                      ASS.AddTime ,
                                                                                                                                      ASS.EditUserId ,
                                                                                                                                      ASS.EditTime ,
                                                                                                                                      ASS.IsDeleted ,
                                                                                                                                      ASS.SpikeId ,
                                                                                                                                      ASS.ProductSku ,
                                                                                                                                      ASS.Price ,
                                                                                                                                      ASS.SpikeStock ,
                                                                                                                                      ASS.Limit ,
                                                                                                                                      ASS.Stock,
                                                                                                                                      P.Name AS 'ProductName',
                                                                                                                                      P.ImgUrl AS 'ProductImgUrl',
                                                                                                                                      MAX(PS.MarketPrice) AS 'MarketPrice'") ?? new List<SpikeProductResponse>();

                    response.Add(spike);
                });

                return response;
            }
        }


        public Activity_Spike FindActivity_Spike(int id)
        {
            using (var Db = DbConfig.GetInstance())
            {
                return Db.Queryable<Activity_Spike>().Where(m => m.Id==id).FirstOrDefault();
            }
        }

        public Activity_SpikeSpec GetSpikeProduct(int SpikeId, string sku)
        {
            using (var Db = DbConfig.GetInstance())
            {
                return Db.Queryable<Activity_SpikeSpec>().Where(m => m.SpikeId == SpikeId && m.ProductSku == sku).FirstOrDefault();
            }
        }

        #endregion

    }
}
